package modele;

import java.util.TreeSet;
import java.util.SortedSet;

import java.io.Writer;

import java.rmi.server.UnicastRemoteObject;

public class ParcoursImpl extends UnicastRemoteObject implements Parcours {

	/**
	 * 
	 */
	private static final long serialVersionUID = 5L;
	static int numero = 0;

	Bd bd;
	Integer ident;
	Object[] obj = new Object[11];
	SortedSet<Fiche> demandes;
	SortedSet<Dossier> propositions;
	


	/**
	 *	Pour la creation d'un parcours a partir de l'importation d'un fichier
	 *  Le format du fichier :
	 *  Nom;Acronyme;Quota;Obligatoires;Choix 1;Choix 2
	 **/
	public ParcoursImpl(Bd bd, String[] unParcours) throws Exception {
		ident = new Integer(numero++);
		this.bd = bd;
		setIntitule(unParcours[0]);
		setSigle(unParcours[1]);
		obj[2] = unParcours[2];
		obj[3] = unParcours[3];
		obj[4] = unParcours[4];
		obj[5] = unParcours[5];

		obj[6] = new TreeSet<UniteEnseignement>(new ComparatorUE());
		obj[7] = new TreeSet<UniteEnseignement>(new ComparatorUE());
		obj[8] = new TreeSet<UniteEnseignement>(new ComparatorUE());
		demandes = new TreeSet<Fiche>(new ComparatorFiche());
		propositions = new TreeSet<Dossier>(new ComparatorDossier());
	}

	static public int getNumero() throws Exception {
		return numero;
	}

	static public void setNumero(int max) throws Exception {
		numero = max;
	}

	public void setIntitule(String nom) throws Exception {
		obj[0] = new String(nom);
	}

	public void setSigle(String nom) throws Exception {
		obj[1] = new String(nom);
	}

	public void setQuota(int nb) throws Exception {
		obj[2] = new Integer(Math.max(nb,0));
	}

	public int getIdent() throws Exception {
		return ident;
	}

	public String getIntitule() throws Exception {
		return (String)obj[0];
	}

	public String getSigle() throws Exception {
		return (String)obj[1];
	}

	public int getQuota() throws Exception {
		return Integer.valueOf((String) obj[2]).intValue(); 
	}

	public Object[] getObjet() throws Exception {
		int[] nb = new int[bd.getParcours().size()];
		for (int i=0; i<nb.length; i++)
			nb[i] = 0;
		for (Fiche fic : demandes)
			nb[fic.getIndiceChoix()]++;
		StringBuffer sb = new StringBuffer(demandes.size()+" [");
		for (int i=0; i<nb.length; i++)
			if (i<nb.length-1)
				sb.append(nb[i]+", ");
			else
				sb.append(nb[i]);
		sb.append("]");
		obj[9] = sb;
		obj[10] = new Integer(propositions.size());
		return obj;
	}

	public String[] getInfo() throws Exception {
		Object[] aux = getObjet();
		String[] info = new String[aux.length];
		for (int i=0; i<aux.length; i++)
			info[i] = aux[i].toString();
		return info;
	}
	
	public int getNbPropositions() throws Exception {
		return propositions.size();
	}

	public int getNbUeObligatoires() throws Exception  {
		return Integer.valueOf((String) obj[3]).intValue(); 
	}

	public int getNbUeChoix1() throws Exception  {
		return Integer.valueOf((String) obj[4]).intValue(); 
	}

	public int getNbUeChoix2() throws Exception  {
		return Integer.valueOf((String) obj[5]).intValue(); 
	}

	@SuppressWarnings("unchecked")
	public SortedSet<UniteEnseignement> getUeObligatoires() throws Exception {
		return (SortedSet<UniteEnseignement>)obj[6];
	}

	@SuppressWarnings("unchecked")
	public SortedSet<UniteEnseignement> getUeChoix1() throws Exception  {
		return (SortedSet<UniteEnseignement>)obj[7];
	}

	@SuppressWarnings("unchecked")
	public SortedSet<UniteEnseignement> getUeChoix2() throws Exception  {
		return (SortedSet<UniteEnseignement>)obj[8];
	}

	public SortedSet<Fiche> getDemandes() throws Exception {
		return demandes;
	}

	public SortedSet<Dossier> getPropositions() throws Exception {
		return propositions;
	}

	@SuppressWarnings("unchecked")
	public boolean addObligatoire(UniteEnseignement ue) throws Exception {
		return ((SortedSet<UniteEnseignement>)obj[6]).add(ue);
	}

	@SuppressWarnings("unchecked")
	public boolean addChoix1(UniteEnseignement ue) throws Exception {
		return ((SortedSet<UniteEnseignement>)obj[7]).add(ue);
	}

	@SuppressWarnings("unchecked")
	public boolean addChoix2(UniteEnseignement ue) throws Exception {
		return ((SortedSet<UniteEnseignement>)obj[8]).add(ue);
	}

	public boolean addDemande(Fiche f) throws Exception {
		return demandes.add(f);
	}

	public boolean addProposition(Dossier e) throws Exception {
		if (propositions.size()<getQuota()){
			return propositions.add(e);
		}
		return false;
	}

	@SuppressWarnings("unchecked")
	public boolean removeObligatoire(UniteEnseignement ue) throws Exception {
		return ((SortedSet<UniteEnseignement>)obj[6]).remove(ue);
	}

	@SuppressWarnings("unchecked")
	public boolean removeChoix1(UniteEnseignement ue) throws Exception {
		return ((SortedSet<UniteEnseignement>)obj[7]).remove(ue);
	}

	@SuppressWarnings("unchecked")
	public boolean removeChoix2(UniteEnseignement ue) throws Exception {
		return ((SortedSet<UniteEnseignement>)obj[8]).remove(ue);
	}

	public boolean removeDemande(Fiche f) throws Exception {
		return demandes.remove(f);
	}

	public boolean removeProposition(Dossier e) throws Exception {
		return propositions.remove(e);
	}

	public void clearPropositions() throws Exception {
		propositions.clear();
	}

	public void clearDemandes() throws Exception {
		demandes.clear();
	}

	public String toString() {
		return (String)obj[1];
	}

	public void imprimer(Writer file) throws Exception {

		file.write("\\cleardoublepage\n"+
				"\\section*{"+getIntitule()+"}\n"+
				"\\begin{longtable}{lrr}\n"+
				"\\endhead\n\\hline\n"+
				"Quota&&"+getQuota()+"\\\\\n"+
				"Nombre de demandes &&"+this.getDemandes().size()+"\\\\\n"+
				"Nombre de propositions&&"+propositions.size()+"\\\\\n"+
				"\\hline\n"+
		"\\caption*{Liste des UE obligatoires}\\\\\n");
		for (UniteEnseignement ue : getUeObligatoires()){
			file.write(ue.getIntitule()+"&"+ue.getDemandes().size()+"&"+ue.getPropositions().size()+"\\\\\n");
		}
		file.write("\\hline\n"+"\\caption*{"+getNbUeChoix1()+" UE au choix parmi}\\\\\n");
		for (UniteEnseignement ue : getUeChoix1())
			file.write(ue.getIntitule()+"&"+ue.getDemandes().size()+"&"+ue.getPropositions().size()+"\\\\\n");
		file.write("\\hline\n"+
				"\\caption*{"+getNbUeChoix2()+" UE au choix parmi}\\\\\n");
		for (UniteEnseignement ue : getUeChoix2()) {
			file.write(ue.getIntitule()+"&"+ue.getDemandes().size()+"&"+ue.getPropositions().size()+"\\\\\n");
		}
		file.write("\\hline\n"+
		"\\end{longtable}\n");
		
		//listes des demandes classées par voeux
		if (demandes.size()>0) {
			file.write("\\newpage\n"+
					"\\subsection*{"+getIntitule()+" : les demandes}\n");
			file.write("\\begin{scriptsize}\n"+
					"\\begin{longtable}{rlllrp{13cm}}\n"+
			"\\endhead\n\\hline\n");
			SortedSet<Fiche> aux = new TreeSet<Fiche>(new ComparatorFicheMoyenne());
			for (Fiche fic : demandes)
				aux.add(fic);
			int choix = -1;
			for (Fiche fic : aux){
				if (fic.getIndiceChoix() > choix){
					choix = fic.getIndiceChoix();
					file.write("\\hline\n"+
							"\\caption*{V\\oe{}u "+(choix+1)+
					"}\\\\\n\\nopagebreak ");
				}
				Dossier dos = fic.getDossier();
				Etudiant etu = dos.getEtudiant();
				// un asterix en debut de ligne indique un REFUS pour ce parcours
				if (!dos.getEvaluation().isOK() || dos.getParcoursInterdits().contains(this))
					file.write("*");
				if (etu.getRedoublant())
					file.write("R ");
				if (etu.getFormationContinue())
					file.write("FC ");
				String orig=etu.getEtablissementOrigine();
				if (orig.length()>50) orig=orig.substring(0,50);
				file.write(etu.getIdApoflux()+"&"+
						etu.getNom()+"&"+
						etu.getPrenom()+"&"+
						orig+"&"+
						dos.getNoteDossier()+"&"+
						dos.getDemande().getListeParcours()+"\\\\\\hline\n");
			}
			file.write("\\end{longtable}\n"+
			"\\end{scriptsize}\n");
		}
		
		//liste des candidats retenus
		if (propositions.size()>0) {
			file.write("\\newpage\n");
			file.write("\\subsection*{"+getIntitule()+" : les candidats retenus ("+propositions.size()+")}\n");
			SortedSet<Dossier> aux = new TreeSet<Dossier>(new ComparatorDossierMoyenne());
			for (Dossier dos : propositions)
				aux.add(dos);
			file.write("\\begin{scriptsize}\n\\begin{tabular}{|lrlllrllllr|}\n\\hline\n");
			for (Dossier dos : aux) {
				if(dos.getProposition()!=null)
					dos.getProposition().imprimer(file);
			}
			//page suivante : on voit toutes les UE
			file.write("\\end{tabular}\n\\end{scriptsize}\n\\newpage\n");
			file.write("\\subsection*{"+getIntitule()+" : ("+propositions.size()+")}\n");
			aux = new TreeSet<Dossier>(new ComparatorDossierNom());
			for (Dossier dos : propositions)
				aux.add(dos);
			file.write("\\begin{scriptsize}\n"+
					"\\begin{longtable}{lllllp{4cm}p{4cm}}\n"+
			"\\endhead\n\\hline\n");
			for (Dossier dos : aux){
				file.write("&");
				Etudiant etu = dos.getEtudiant();
				String orig=etu.getEtablissementOrigine();
				if (orig.length()>50) 
					orig=orig.substring(0,50);
				
				file.write(etu.getNom()+"&"+etu.getPrenom()+"&"+
						orig+"&"+getUeObligatoires()+"&"+dos.getProposition().getUesChoix1()+"&"+
						dos.getProposition().getUesChoix2()+"\\\\\\hline\n");
			}
			file.write("\\end{longtable}\n"+
			"\\end{scriptsize}\n");
		}
	}

	public void imprimerSynthese(Writer file)
	throws Exception {
		file.write("\\newpage\n"+
				"\\section*{"+getIntitule()+"}\n"+
				"\\begin{longtable}{lrr}\n"+
				"\\endhead\n\\hline\n"+
				"Quota&&"+getQuota()+"\\\\\n"+
				"Nombre de demandes &&"+this.getDemandes().size()+"\\\\\n"+
				"Nombre de propositions&&"+propositions.size()+"\\\\\n"+
				"\\hline\n"+
		"\\caption*{Liste des UE obligatoires}\\\\\n");
		for (UniteEnseignement ue : getUeObligatoires()){
			file.write(ue.getIntitule()+"~("+ue.getSigle()+")"+"&"+
					ue.getDemandes().size()+"&"+
					ue.getPropositions().size()+"\\\\\n");
		}
		file.write("\\hline\n"+
				"\\caption*{"+getNbUeChoix1()+" UE au choix parmi}\\\\\n");
		for (UniteEnseignement ue : getUeChoix1()) {
			file.write(ue.getIntitule()+"~("+ue.getSigle()+")"+"&"+
					ue.getDemandes().size()+"&"+
					ue.getPropositions().size()+"\\\\\n");
		}
		file.write("\\hline\n"+
				"\\caption*{"+getNbUeChoix2()+" UE au choix parmi}\\\\\n");
		for (UniteEnseignement ue : getUeChoix2()) {
			file.write(ue.getIntitule()+"~("+ue.getSigle()+")"+"&"+
					ue.getDemandes().size()+"&"+
					ue.getPropositions().size()+"\\\\\n");
		}
		file.write("\\hline\n"+
		"\\end{longtable}\n");
	}

}
